/**
 *
 */
package 线程;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.collections.set.SynchronizedSet;
import org.junit.Test;

/**
 * 可重入锁 比synchronized 更加强大
 *
 * @Title:
 * @author zhoujie
 * @date 2018年7月10日 下午1:41:14
 *
 */
public class ReentrantLockDemo {
    static Lock lock = new ReentrantLock();
    static int num = 1;
    CountDownLatch cd2 = new CountDownLatch(1);
    static Condition c1 = lock.newCondition();

    /**
     * 交替打印1-100 1线程打印奇数 2线程打印偶数
     */
    @Test
    public void test02() {

        new Thread(() -> {
            try {
                prilnt1();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                prilnt2();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        try {
            cd2.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } // 等所有线程都执行完毕
    }

    public void prilnt1() throws Exception {
        while (num <= 100) {
            lock.lock();
            if (num % 2 == 1) {
                System.out.println(Thread.currentThread().getName() + "   " + (num++));
                c1.signalAll();
            } else {
                c1.await();
            }
            lock.unlock();
        }
        cd2.countDown();
    }

    public void prilnt2() throws Exception {
        while (num <= 100) {
            lock.lock();
            if (num % 2 == 0) {
                System.out.println(Thread.currentThread().getName() + "   " + (num++));
                c1.signalAll();
            } else {
                c1.await();
            }
            lock.unlock();
        }
        cd2.countDown();
    }

}
